﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MathWorks.MATLAB.NET.Arrays;
using MathWorks.MATLAB.NET.Utility;
using matlab_function;

namespace Image_Test1
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }
        public Color[,] Buffer;
        public Bitmap ImageFile;
        public double[,] R_Real, R_Imag, G_Real, G_Imag, B_Real, B_Imag;
        public double[,] R, G, B;

       
        private void Start_Button_Click(object sender, EventArgs e)
        {
            Start();
        }

        private void Inverse_Button_Click(object sender, EventArgs e)
        {
            //EngMATAccess mat = new EngMATAccess();
            mat mat1 = new mat();

            double[,] R1 = new double[ImageFile.Height, ImageFile.Width];
            double[,] G1 = new double[ImageFile.Height, ImageFile.Width];
            double[,] B1 = new double[ImageFile.Height, ImageFile.Width];

            #region Deal With Matlab

            #region Old
            /*
            
            mat.SetMatrix("R_Real", R_Real);
            mat.SetMatrix("R_Imag", R_Imag);

            mat.SetMatrix("G_Real", G_Real);
            mat.SetMatrix("G_Imag", G_Imag);

            mat.SetMatrix("B_Real", B_Real);
            mat.SetMatrix("B_Imag", B_Imag);

            mat.Evaluate("R = ReverseTrans(R_Real,R_Imag); G = ReverseTrans(G_Real,G_Imag); B = ReverseTrans(B_Real,B_Imag);");

            mat.GetMatrix("R", ref R);
            mat.GetMatrix("G", ref  G);
            mat.GetMatrix("B", ref  B);
            */
            #endregion

            MWNumericArray new_r = (MWNumericArray)mat1.ReverseTrans((MWNumericArray)R_Real, (MWNumericArray)R_Imag);
            R1 = (double[,])new_r.ToArray();
            MWNumericArray new_g = (MWNumericArray)mat1.ReverseTrans((MWNumericArray)G_Real, (MWNumericArray)G_Imag);
            G1 = (double[,])new_g.ToArray();
            MWNumericArray new_b = (MWNumericArray)mat1.ReverseTrans((MWNumericArray)B_Real, (MWNumericArray)B_Imag);
            B1 = (double[,])new_b.ToArray();

            #endregion

            #region Display Image after Inverse
            Bitmap Image = new Bitmap(ImageFile.Width, ImageFile.Height);
            for (int i = 0; i < ImageFile.Height; i++)
                for (int j = 0; j < ImageFile.Width; j++)
                    Image.SetPixel(j, i, Color.FromArgb((int)R1[i, j], (int)G1[i, j], (int)B1[i, j]));
            pictureBox5.Image = Image;
            #endregion
            
        }

        public void Intiallize(Bitmap Image)
        {
            ImageFile = Image;
            //for (int i = 0; i < Image.Width; i++)
            //{
            //    for (int j = 0; j < Image.Height; j++)
            //    {
            //        ImageFile.SetPixel(j,i,Image.GetPixel(i,j));
            //    }
            //}
            pictureBox1.Image = ImageFile;
            R = new double[ImageFile.Height, ImageFile.Width];
            G = new double[ImageFile.Height, ImageFile.Width];
            B = new double[ImageFile.Height, ImageFile.Width];
            Buffer = new Color[ImageFile.Height, ImageFile.Width];

            for (int i = 0; i < ImageFile.Height; i++)
            {
                for (int j = 0; j < ImageFile.Width; j++)
                {
                    Buffer[i, j] = ImageFile.GetPixel(j, i);
                    R[i, j] = Buffer[i, j].R;
                    G[i, j] = Buffer[i, j].G;
                    B[i, j] = Buffer[i, j].B;
                }
            }


        }
        public void Start()
        {
            mat mat1 = new mat();

            R_Real = new double[ImageFile.Height, ImageFile.Width];
            R_Imag = new double[ImageFile.Height, ImageFile.Width];

            G_Real = new double[ImageFile.Height, ImageFile.Width];
            G_Imag = new double[ImageFile.Height, ImageFile.Width];

            B_Real = new double[ImageFile.Height, ImageFile.Width];
            B_Imag = new double[ImageFile.Height, ImageFile.Width];

            #region Deal with Matlap

            #region Old code with link matlab
            /*
            mat.SetMatrix("R", R);
            mat.SetMatrix("G", G);
            mat.SetMatrix("B", B);

            mat.Evaluate("R_Real = ConvertReal(R); G_Real = ConvertReal(G); B_Real = ConvertReal(B);");
            mat.Evaluate("R_Imag = ConvertImag(R); G_Imag = ConvertImag(G); B_Imag = ConvertImag(B);");


            mat.GetMatrix("R_Real", ref R_Real);
            mat.GetMatrix("R_Imag", ref R_Imag);

            mat.GetMatrix("G_Real", ref G_Real);
            mat.GetMatrix("G_Imag", ref G_Imag);

            mat.GetMatrix("B_Real", ref B_Real);
            mat.GetMatrix("B_Imag", ref B_Imag);
            */
            #endregion

            MWNumericArray new_r = (MWNumericArray)mat1.ConvertReal((MWNumericArray)R);
            R_Real = (double[,])new_r.ToArray();
            MWNumericArray new_g = (MWNumericArray)mat1.ConvertReal((MWNumericArray)G);
            G_Real = (double[,])new_g.ToArray();
            MWNumericArray new_b = (MWNumericArray)mat1.ConvertReal((MWNumericArray)B);
            B_Real = (double[,])new_b.ToArray();

            new_r = (MWNumericArray)mat1.ConvertImag((MWNumericArray)R);
            R_Imag = (double[,])new_r.ToArray();
            new_g = (MWNumericArray)mat1.ConvertImag((MWNumericArray)G);
            G_Imag = (double[,])new_g.ToArray();
            new_b = (MWNumericArray)mat1.ConvertImag((MWNumericArray)B);
            B_Imag = (double[,])new_b.ToArray();


            #endregion

            #region Equation
            double[,] magnitude_R = new double[ImageFile.Height, ImageFile.Width];
            double[,] magnitude_G = new double[ImageFile.Height, ImageFile.Width];
            double[,] magnitude_B = new double[ImageFile.Height, ImageFile.Width];

            double Eps = 0.1;
            for (int i = 0; i < ImageFile.Height; i++)
            {
                for (int j = 0; j < ImageFile.Width; j++)
                {
                    magnitude_R[i, j] = Math.Sqrt((Math.Pow(R_Real[i, j], 2.0) + Math.Pow(R_Imag[i, j], 2.0)));
                    magnitude_R[i, j] = Math.Log10(magnitude_R[i, j] + Eps);

                    magnitude_G[i, j] = Math.Sqrt((Math.Pow(G_Real[i, j], 2.0) + Math.Pow(G_Imag[i, j], 2.0)));
                    magnitude_G[i, j] = Math.Log10(magnitude_G[i, j] + Eps);

                    magnitude_B[i, j] = Math.Sqrt((Math.Pow(B_Real[i, j], 2.0) + Math.Pow(B_Imag[i, j], 2.0)));
                    magnitude_B[i, j] = Math.Log10(magnitude_B[i, j] + Eps);
                }
            }

            R = Normalization(magnitude_R, ImageFile.Height, ImageFile.Width);
            G = Normalization(magnitude_G, ImageFile.Height, ImageFile.Width);
            B = Normalization(magnitude_B, ImageFile.Height, ImageFile.Width);

            #endregion

            #region Display Red & Green & Blue

            Bitmap RImage = new Bitmap(R.GetLength(1), R.GetLength(0));
            Bitmap GImage = new Bitmap(R.GetLength(1), R.GetLength(0));
            Bitmap BImage = new Bitmap(R.GetLength(1), R.GetLength(0));

            for (int i = 0; i < R.GetLength(0); i++)
                for (int j = 0; j < R.GetLength(1); j++)
                    RImage.SetPixel(j, i, Color.FromArgb((int)R[i, j], 0, 0));

            for (int i = 0; i < R.GetLength(0); i++)
                for (int j = 0; j < R.GetLength(1); j++)
                    GImage.SetPixel(j, i, Color.FromArgb(0, (int)G[i, j], 0));

            for (int i = 0; i < R.GetLength(0); i++)
                for (int j = 0; j < R.GetLength(1); j++)
                    BImage.SetPixel(j, i, Color.FromArgb(0, 0, (int)B[i, j]));

            //DisplayPicture2.Image = RImage;
            //DisplayPicture3.Image = GImage;
            //DisplayPicture4.Image = BImage;
            pictureBox2.Image = RImage;
            pictureBox3.Image = GImage;
            pictureBox4.Image = BImage;
            #endregion

        }
        public static double[,] Normalization(double[,] norm_arr, int height, int width)
        {
            double max = 0;
            double min = 1000;

            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    if (norm_arr[i, j] > max)
                        max = norm_arr[i, j];
                    if (norm_arr[i, j] < min)
                        min = norm_arr[i, j];
                }
            }
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    norm_arr[i, j] = ((norm_arr[i, j] - min) / (max - min)) * 255;
                }
            }
            return norm_arr;


        }
    }
}
